home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Compilers / digital marsC compier / dm / stl / valarray < prev    next >
Encoding:
Text File  |  2000-06-08  |  51.7 KB  |  1,774 lines

  1. /*
  2.  * Copyright (c) 1999
  3.  * Silicon Graphics Computer Systems, Inc.
  4.  *
  5.  * Permission to use, copy, modify, distribute and sell this software
  6.  * and its documentation for any purpose is hereby granted without fee,
  7.  * provided that the above copyright notice appear in all copies and
  8.  * that both that copyright notice and this permission notice appear
  9.  * in supporting documentation.  Silicon Graphics makes no
  10.  * representations about the suitability of this software for any
  11.  * purpose.  It is provided "as is" without express or implied warranty.
  12.  */ 
  13.  
  14. #ifndef __SGI_STL_VALARRAY
  15. #define __SGI_STL_VALARRAY
  16.  
  17. #include <type_traits.h>
  18. #include <math.h>
  19. #include <algorithm>
  20. #include <numeric>
  21. #include <limits>
  22. #include <new>
  23.  
  24.  
  25. __STL_BEGIN_NAMESPACE
  26.  
  27. class slice;
  28. class gslice;
  29.  
  30. template <class _Tp> class valarray;
  31. template <class _Tp> class slice_array;
  32. template <class _Tp> class gslice_array;
  33. template <class _Tp> class mask_array;
  34. template <class _Tp> class indirect_array;
  35.  
  36. //----------------------------------------------------------------------
  37. // class valarray
  38.  
  39. // Base class to handle memory allocation and deallocation.  We can't just
  40. // use vector<>, because vector<bool> would be unsuitable as an internal 
  41. // representation for valarray<bool>.
  42.  
  43. template <class _Tp> 
  44. struct _Valarray_base
  45. {
  46.   _Tp*   _M_first;
  47.   size_t _M_size;
  48.  
  49.   _Valarray_base() : _M_first(0), _M_size(0) {}
  50.   _Valarray_base(size_t __n) : _M_first(0), _M_size(0) { _M_allocate(__n); }
  51.   ~_Valarray_base() { _M_deallocate(); }
  52.  
  53.   void _M_allocate(size_t __n) {
  54.     if (__n != 0) {
  55.       _M_first = static_cast<_Tp*>(malloc(__n * sizeof(_Tp)));
  56.       _M_size  = __n;
  57. #   if !defined(__STL_NO_BAD_ALLOC) && defined(__STL_USE_EXCEPTIONS)
  58.       if (_M_first == 0) {
  59.         _M_size = 0;
  60.         throw std::bad_alloc();
  61.       }
  62. #   endif
  63.     }
  64.     else {
  65.       _M_first = 0;
  66.       _M_size = 0;
  67.     }
  68.   }
  69.  
  70.   void _M_deallocate() {
  71.     free(_M_first);
  72.     _M_first = 0;
  73.     _M_size = 0;
  74.   }
  75. };
  76.  
  77. template <class _Tp> 
  78. class valarray : private _Valarray_base<_Tp>
  79. {
  80.   friend class gslice;
  81.  
  82. public:
  83.   typedef _Tp value_type;
  84.  
  85.   // Basic constructors
  86.   valarray() : _Valarray_base<_Tp>() {}
  87.   valarray(size_t __n) : _Valarray_base<_Tp>(__n)
  88.     { uninitialized_fill_n(this->_M_first, this->_M_size, value_type()); }
  89.   valarray(const value_type& __x, size_t __n) : _Valarray_base<_Tp>(__n)
  90.     { uninitialized_fill_n(this->_M_first, this->_M_size, __x); }
  91.   valarray(const value_type* __p, size_t __n) : _Valarray_base<_Tp>(__n)
  92.     { uninitialized_copy(__p, __p + __n, this->_M_first); } 
  93.   valarray(const valarray& __x) : _Valarray_base<_Tp>(__x._M_size) {
  94.     uninitialized_copy(__x._M_first, __x._M_first + __x._M_size,
  95.                        this->_M_first);
  96.   }
  97.  
  98.   // Constructors from auxiliary array types
  99.   valarray(const slice_array<_Tp>&);
  100.   valarray(const gslice_array<_Tp>&);
  101.   valarray(const mask_array<_Tp>&);
  102.   valarray(const indirect_array<_Tp>&);
  103.  
  104.   // Destructor
  105.   ~valarray() { destroy(this->_M_first, this->_M_first + this->_M_size); }
  106.  
  107.   // Extension: constructor that doesn't initialize valarray elements to a
  108.   // specific value.  This is faster for types such as int and double.
  109. private:
  110.   void _M_initialize(__true_type) {}
  111.   void _M_initialize(__false_type)
  112.     { uninitialized_fill_n(this->_M_first, this->_M_size, value_type()); }
  113.  
  114. public:
  115.   struct _NoInit {};
  116.   valarray(size_t __n, _NoInit) : _Valarray_base<_Tp>(__n) {
  117.     typedef typename __type_traits<_Tp>::has_trivial_default_constructor
  118.             _Is_Trivial;
  119.     _M_initialize(_Is_Trivial());
  120.   }
  121.  
  122. public:                         // Assignment
  123.   // Basic assignment.  Note that 'x = y' is undefined if x.size() != y.size()
  124.   valarray& operator=(const valarray& __x) {
  125.     if (this != &__x)
  126.       copy(__x._M_first, __x._M_first + __x._M_size, this->_M_first);
  127.     return *this;
  128.   }
  129.  
  130.   // Scalar assignment
  131.   valarray& operator=(const value_type& __x) {
  132.     fill_n(this->_M_first, this->_M_size, __x);
  133.     return *this;
  134.   }
  135.  
  136.   // Assignment of auxiliary array types
  137.   valarray& operator=(const slice_array<_Tp>&);
  138.   valarray& operator=(const gslice_array<_Tp>&);
  139.   valarray& operator=(const mask_array<_Tp>&);
  140.   valarray& operator=(const indirect_array<_Tp>&);
  141.  
  142. public:                         // Element access
  143.   value_type  operator[](size_t __n) const { return this->_M_first[__n]; }
  144.   value_type& operator[](size_t __n)       { return this->_M_first[__n]; }
  145.   size_t size() const { return this->_M_size; }
  146.  
  147. public:                         // Subsetting operations with auxiliary type
  148.   valarray            operator[](slice) const;
  149.   slice_array<_Tp>    operator[](slice);
  150.   valarray            operator[](gslice) const;
  151.   gslice_array<_Tp>   operator[](gslice);  
  152.   valarray            operator[](const valarray<bool>&) const;
  153.   mask_array<_Tp>     operator[](const valarray<bool>&);
  154.   valarray            operator[](const valarray<size_t>&) const;
  155.   indirect_array<_Tp> operator[](const valarray<size_t>&);
  156.   
  157. public:                         // Unary operators.
  158.   valarray operator+() const { return *this; }
  159.  
  160.   valarray operator-() const {
  161.     valarray __tmp(this->size(), _NoInit());
  162.     for (size_t __i = 0; __i < this->size(); ++__i)
  163.       __tmp[__i] = -(*this)[__i];
  164.     return __tmp;
  165.   }
  166.   
  167.   valarray operator~() const {
  168.     valarray __tmp(this->size(), _NoInit());
  169.     for (size_t __i = 0; __i < this->size(); ++__i)
  170.       __tmp[__i] = ~(*this)[__i];
  171.     return __tmp;
  172.   }
  173.  
  174.   valarray<bool> operator!() const {
  175.     valarray<bool> __tmp(this->size(), valarray<bool>::_NoInit());
  176.     for (size_t __i = 0; __i < this->size(); ++__i)
  177.       __tmp[__i] = !(*this)[__i];
  178.     return __tmp;
  179.   }
  180.  
  181. public:                         // Scalar computed assignment.
  182.   valarray& operator*= (const value_type& __x) {
  183.     for (size_t __i = 0; __i < this->size(); ++__i)
  184.       (*this)[__i] *= __x;
  185.     return *this;
  186.   }
  187.     
  188.   valarray& operator/= (const value_type& __x) {
  189.     for (size_t __i = 0; __i < this->size(); ++__i)
  190.       (*this)[__i] /= __x;
  191.     return *this;
  192.   }
  193.  
  194.   valarray& operator%= (const value_type& __x) {
  195.     for (size_t __i = 0; __i < this->size(); ++__i)
  196.       (*this)[__i] %= __x;
  197.     return *this;
  198.   }
  199.  
  200.   valarray& operator+= (const value_type& __x) {
  201.     for (size_t __i = 0; __i < this->size(); ++__i)
  202.       (*this)[__i] += __x;
  203.     return *this;
  204.   }
  205.  
  206.   valarray& operator-= (const value_type& __x) {
  207.     for (size_t __i = 0; __i < this->size(); ++__i)
  208.       (*this)[__i] -= __x;
  209.     return *this;
  210.   }
  211.  
  212.   valarray& operator^= (const value_type& __x) {
  213.     for (size_t __i = 0; __i < this->size(); ++__i)
  214.       (*this)[__i] ^= __x;
  215.     return *this;
  216.   }
  217.  
  218.   valarray& operator&= (const value_type& __x) {
  219.     for (size_t __i = 0; __i < this->size(); ++__i)
  220.       (*this)[__i] &= __x;
  221.     return *this;
  222.   }
  223.  
  224.   valarray& operator|= (const value_type& __x) {
  225.     for (size_t __i = 0; __i < this->size(); ++__i)
  226.       (*this)[__i] |= __x;
  227.     return *this;
  228.   }
  229.  
  230.   valarray& operator<<= (const value_type& __x) {
  231.     for (size_t __i = 0; __i < this->size(); ++__i)
  232.       (*this)[__i] <<= __x;
  233.     return *this;
  234.   }
  235.  
  236.   valarray& operator>>= (const value_type& __x) {
  237.     for (size_t __i = 0; __i < this->size(); ++__i)
  238.       (*this)[__i] >>= __x;
  239.     return *this;
  240.   }
  241.  
  242. public:                         // Array computed assignment.
  243.   valarray& operator*= (const valarray& __x) {
  244.     for (size_t __i = 0; __i < this->size(); ++__i)
  245.       (*this)[__i] *= __x[__i];
  246.     return *this;
  247.   }
  248.     
  249.   valarray& operator/= (const valarray& __x) {
  250.     for (size_t __i = 0; __i < this->size(); ++__i)
  251.       (*this)[__i] /= __x[__i];
  252.     return *this;
  253.   }
  254.  
  255.   valarray& operator%= (const valarray& __x) {
  256.     for (size_t __i = 0; __i < this->size(); ++__i)
  257.       (*this)[__i] %= __x[__i];
  258.     return *this;
  259.   }
  260.  
  261.   valarray& operator+= (const valarray& __x) {
  262.     for (size_t __i = 0; __i < this->size(); ++__i)
  263.       (*this)[__i] += __x[__i];
  264.     return *this;
  265.   }
  266.  
  267.   valarray& operator-= (const valarray& __x) {
  268.     for (size_t __i = 0; __i < this->size(); ++__i)
  269.       (*this)[__i] -= __x[__i];
  270.     return *this;
  271.   }
  272.  
  273.   valarray& operator^= (const valarray& __x) {
  274.     for (size_t __i = 0; __i < this->size(); ++__i)
  275.       (*this)[__i] ^= __x[__i];
  276.     return *this;
  277.   }
  278.  
  279.   valarray& operator&= (const valarray& __x) {
  280.     for (size_t __i = 0; __i < this->size(); ++__i)
  281.       (*this)[__i] &= __x[__i];
  282.     return *this;
  283.   }
  284.  
  285.   valarray& operator|= (const valarray& __x) {
  286.     for (size_t __i = 0; __i < this->size(); ++__i)
  287.       (*this)[__i] |= __x[__i];
  288.     return *this;
  289.   }
  290.  
  291.   valarray& operator<<= (const valarray& __x) {
  292.     for (size_t __i = 0; __i < this->size(); ++__i)
  293.       (*this)[__i] <<= __x[__i];
  294.     return *this;
  295.   }
  296.  
  297.   valarray& operator>>= (const valarray& __x) {
  298.     for (size_t __i = 0; __i < this->size(); ++__i)
  299.       (*this)[__i] >>= __x[__i];
  300.     return *this;
  301.   }
  302.  
  303. public:                         // Other member functions.
  304.  
  305.   // The result is undefined for zero-length arrays
  306.   value_type sum() const {
  307.     return accumulate(this->_M_first + 1, this->_M_first + this->_M_size,
  308.                       (*this)[0]);
  309.   }
  310.  
  311.   // The result is undefined for zero-length arrays
  312.   value_type min() const {
  313.     return *min_element(this->_M_first + 0, this->_M_first + this->_M_size);
  314.   }
  315.  
  316.   value_type max() const {
  317.     return *max_element(this->_M_first + 0, this->_M_first + this->_M_size);
  318.   }
  319.  
  320.   valarray shift(int __n) const;
  321.   valarray cshift(int __n) const;
  322.  
  323.   valarray apply(value_type __f(value_type)) const {
  324.     valarray __tmp(this->size());
  325.     transform(this->_M_first, this->_M_first + this->_M_size, __tmp._M_first,
  326.               __f);
  327.     return __tmp;
  328.   }
  329.   valarray apply(value_type __f(const value_type&)) const {
  330.     valarray __tmp(this->size());
  331.     transform(this->_M_first, this->_M_first + this->_M_size, __tmp._M_first,
  332.               __f);
  333.     return __tmp;
  334.   }
  335.   
  336.   void resize(size_t __n, value_type __x = value_type()) {
  337.     destroy(this->_M_first, this->_M_first + this->_M_size);
  338.     this->_Valarray_base<_Tp>::_M_deallocate();
  339.     this->_Valarray_base<_Tp>::_M_allocate(__n);
  340.     uninitialized_fill_n(this->_M_first, this->_M_size, __x);
  341.   }
  342. };
  343.  
  344. //----------------------------------------------------------------------
  345. // valarray non-member functions.
  346.  
  347. // Binary arithmetic operations between two arrays.  Behavior is
  348. // undefined if the two arrays do not have the same length.
  349.  
  350. template <class _Tp> 
  351. inline valarray<_Tp> operator*(const valarray<_Tp>& __x,
  352.                                const valarray<_Tp>& __y) {
  353.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  354.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  355.   for (size_t __i = 0; __i < __x.size(); ++__i)
  356.     __tmp[__i] = __x[__i] * __y[__i];
  357.   return __tmp;
  358. }
  359.  
  360. template <class _Tp> 
  361. inline valarray<_Tp> operator/(const valarray<_Tp>& __x,
  362.                                const valarray<_Tp>& __y) {
  363.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  364.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  365.   for (size_t __i = 0; __i < __x.size(); ++__i)
  366.     __tmp[__i] = __x[__i] / __y[__i];
  367.   return __tmp;
  368. }
  369.  
  370. template <class _Tp> 
  371. inline valarray<_Tp> operator%(const valarray<_Tp>& __x,
  372.                                const valarray<_Tp>& __y) {
  373.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  374.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  375.   for (size_t __i = 0; __i < __x.size(); ++__i)
  376.     __tmp[__i] = __x[__i] % __y[__i];
  377.   return __tmp;
  378. }
  379.  
  380. template <class _Tp> 
  381. inline valarray<_Tp> operator+(const valarray<_Tp>& __x,
  382.                                const valarray<_Tp>& __y) {
  383.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  384.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  385.   for (size_t __i = 0; __i < __x.size(); ++__i)
  386.     __tmp[__i] = __x[__i] + __y[__i];
  387.   return __tmp;
  388. }
  389.  
  390. template <class _Tp> 
  391. inline valarray<_Tp> operator-(const valarray<_Tp>& __x,
  392.                                const valarray<_Tp>& __y) {
  393.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  394.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  395.   for (size_t __i = 0; __i < __x.size(); ++__i)
  396.     __tmp[__i] = __x[__i] - __y[__i];
  397.   return __tmp;
  398. }
  399.  
  400. template <class _Tp> 
  401. inline valarray<_Tp> operator^(const valarray<_Tp>& __x,
  402.                                const valarray<_Tp>& __y) {
  403.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  404.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  405.   for (size_t __i = 0; __i < __x.size(); ++__i)
  406.     __tmp[__i] = __x[__i] ^ __y[__i];
  407.   return __tmp;
  408. }
  409.  
  410. template <class _Tp> 
  411. inline valarray<_Tp> operator&(const valarray<_Tp>& __x,
  412.                                const valarray<_Tp>& __y) {
  413.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  414.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  415.   for (size_t __i = 0; __i < __x.size(); ++__i)
  416.     __tmp[__i] = __x[__i] & __y[__i];
  417.   return __tmp;
  418. }
  419.  
  420. template <class _Tp> 
  421. inline valarray<_Tp> operator|(const valarray<_Tp>& __x,
  422.                                const valarray<_Tp>& __y) {
  423.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  424.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  425.   for (size_t __i = 0; __i < __x.size(); ++__i)
  426.     __tmp[__i] = __x[__i] | __y[__i];
  427.   return __tmp;
  428. }
  429.  
  430. template <class _Tp> 
  431. inline valarray<_Tp> operator<<(const valarray<_Tp>& __x,
  432.                                const valarray<_Tp>& __y) {
  433.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  434.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  435.   for (size_t __i = 0; __i < __x.size(); ++__i)
  436.     __tmp[__i] = __x[__i] << __y[__i];
  437.   return __tmp;
  438. }
  439.  
  440. template <class _Tp> 
  441. inline valarray<_Tp> operator>>(const valarray<_Tp>& __x,
  442.                                const valarray<_Tp>& __y) {
  443.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  444.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  445.   for (size_t __i = 0; __i < __x.size(); ++__i)
  446.     __tmp[__i] = __x[__i] >> __y[__i];
  447.   return __tmp;
  448. }
  449.  
  450. // Binary arithmetic operations between an array and a scalar.
  451.  
  452. template <class _Tp> 
  453. inline valarray<_Tp> operator*(const valarray<_Tp>& __x, const _Tp& __c) {
  454.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  455.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  456.   for (size_t __i = 0; __i < __x.size(); ++__i)
  457.     __tmp[__i] = __x[__i]  * __c;
  458.   return __tmp;
  459. }
  460.  
  461. template <class _Tp> 
  462. inline valarray<_Tp> operator*(const _Tp& __c, const valarray<_Tp>& __x) {
  463.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  464.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  465.   for (size_t __i = 0; __i < __x.size(); ++__i)
  466.     __tmp[__i] = __c * __x[__i];
  467.   return __tmp;
  468. }
  469.  
  470. template <class _Tp> 
  471. inline valarray<_Tp> operator/(const valarray<_Tp>& __x, const _Tp& __c) {
  472.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  473.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  474.   for (size_t __i = 0; __i < __x.size(); ++__i)
  475.     __tmp[__i] = __x[__i]  / __c;
  476.   return __tmp;
  477. }
  478.  
  479. template <class _Tp> 
  480. inline valarray<_Tp> operator/(const _Tp& __c, const valarray<_Tp>& __x) {
  481.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  482.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  483.   for (size_t __i = 0; __i < __x.size(); ++__i)
  484.     __tmp[__i] = __c / __x[__i];
  485.   return __tmp;
  486. }
  487.  
  488. template <class _Tp> 
  489. inline valarray<_Tp> operator%(const valarray<_Tp>& __x, const _Tp& __c) {
  490.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  491.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  492.   for (size_t __i = 0; __i < __x.size(); ++__i)
  493.     __tmp[__i] = __x[__i]  % __c;
  494.   return __tmp;
  495. }
  496.  
  497. template <class _Tp> 
  498. inline valarray<_Tp> operator%(const _Tp& __c, const valarray<_Tp>& __x) {
  499.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  500.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  501.   for (size_t __i = 0; __i < __x.size(); ++__i)
  502.     __tmp[__i] = __c % __x[__i];
  503.   return __tmp;
  504. }
  505.  
  506. template <class _Tp> 
  507. inline valarray<_Tp> operator+(const valarray<_Tp>& __x, const _Tp& __c) {
  508.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  509.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  510.   for (size_t __i = 0; __i < __x.size(); ++__i)
  511.     __tmp[__i] = __x[__i]  + __c;
  512.   return __tmp;
  513. }
  514.  
  515. template <class _Tp> 
  516. inline valarray<_Tp> operator+(const _Tp& __c, const valarray<_Tp>& __x) {
  517.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  518.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  519.   for (size_t __i = 0; __i < __x.size(); ++__i)
  520.     __tmp[__i] = __c + __x[__i];
  521.   return __tmp;
  522. }
  523.  
  524. template <class _Tp> 
  525. inline valarray<_Tp> operator-(const valarray<_Tp>& __x, const _Tp& __c) {
  526.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  527.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  528.   for (size_t __i = 0; __i < __x.size(); ++__i)
  529.     __tmp[__i] = __x[__i]  - __c;
  530.   return __tmp;
  531. }
  532.  
  533. template <class _Tp> 
  534. inline valarray<_Tp> operator-(const _Tp& __c, const valarray<_Tp>& __x) {
  535.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  536.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  537.   for (size_t __i = 0; __i < __x.size(); ++__i)
  538.     __tmp[__i] = __c - __x[__i];
  539.   return __tmp;
  540. }
  541.  
  542. template <class _Tp> 
  543. inline valarray<_Tp> operator^(const valarray<_Tp>& __x, const _Tp& __c) {
  544.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  545.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  546.   for (size_t __i = 0; __i < __x.size(); ++__i)
  547.     __tmp[__i] = __x[__i]  ^ __c;
  548.   return __tmp;
  549. }
  550.  
  551. template <class _Tp> 
  552. inline valarray<_Tp> operator^(const _Tp& __c, const valarray<_Tp>& __x) {
  553.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  554.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  555.   for (size_t __i = 0; __i < __x.size(); ++__i)
  556.     __tmp[__i] = __c ^ __x[__i];
  557.   return __tmp;
  558. }
  559.  
  560. template <class _Tp> 
  561. inline valarray<_Tp> operator&(const valarray<_Tp>& __x, const _Tp& __c) {
  562.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  563.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  564.   for (size_t __i = 0; __i < __x.size(); ++__i)
  565.     __tmp[__i] = __x[__i]  & __c;
  566.   return __tmp;
  567. }
  568.  
  569. template <class _Tp> 
  570. inline valarray<_Tp> operator&(const _Tp& __c, const valarray<_Tp>& __x) {
  571.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  572.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  573.   for (size_t __i = 0; __i < __x.size(); ++__i)
  574.     __tmp[__i] = __c & __x[__i];
  575.   return __tmp;
  576. }
  577.  
  578. template <class _Tp> 
  579. inline valarray<_Tp> operator|(const valarray<_Tp>& __x, const _Tp& __c) {
  580.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  581.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  582.   for (size_t __i = 0; __i < __x.size(); ++__i)
  583.     __tmp[__i] = __x[__i]  | __c;
  584.   return __tmp;
  585. }
  586.  
  587. template <class _Tp> 
  588. inline valarray<_Tp> operator|(const _Tp& __c, const valarray<_Tp>& __x) {
  589.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  590.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  591.   for (size_t __i = 0; __i < __x.size(); ++__i)
  592.     __tmp[__i] = __c | __x[__i];
  593.   return __tmp;
  594. }
  595.  
  596. template <class _Tp> 
  597. inline valarray<_Tp> operator<<(const valarray<_Tp>& __x, const _Tp& __c) {
  598.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  599.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  600.   for (size_t __i = 0; __i < __x.size(); ++__i)
  601.     __tmp[__i] = __x[__i]  << __c;
  602.   return __tmp;
  603. }
  604.  
  605. template <class _Tp> 
  606. inline valarray<_Tp> operator<<(const _Tp& __c, const valarray<_Tp>& __x) {
  607.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  608.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  609.   for (size_t __i = 0; __i < __x.size(); ++__i)
  610.     __tmp[__i] = __c << __x[__i];
  611.   return __tmp;
  612. }
  613.  
  614. template <class _Tp> 
  615. inline valarray<_Tp> operator>>(const valarray<_Tp>& __x, const _Tp& __c) {
  616.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  617.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  618.   for (size_t __i = 0; __i < __x.size(); ++__i)
  619.     __tmp[__i] = __x[__i]  >> __c;
  620.   return __tmp;
  621. }
  622.  
  623. template <class _Tp> 
  624. inline valarray<_Tp> operator>>(const _Tp& __c, const valarray<_Tp>& __x) {
  625.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  626.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  627.   for (size_t __i = 0; __i < __x.size(); ++__i)
  628.     __tmp[__i] = __c >> __x[__i];
  629.   return __tmp;
  630. }
  631.  
  632. // Binary logical operations between two arrays.  Behavior is undefined
  633. // if the two arrays have different lengths.  Note that operator== does
  634. // not do what you might at first expect.
  635.  
  636. template <class _Tp> 
  637. inline valarray<bool> operator==(const valarray<_Tp>& __x,
  638.                                  const valarray<_Tp>& __y)
  639. {
  640.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  641.   for (size_t __i = 0; __i < __x.size(); ++__i)
  642.     __tmp[__i] = __x[__i] == __y[__i];
  643.   return __tmp;  
  644. }
  645.  
  646. template <class _Tp> 
  647. inline valarray<bool> operator<(const valarray<_Tp>& __x,
  648.                                 const valarray<_Tp>& __y)
  649. {
  650.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  651.   for (size_t __i = 0; __i < __x.size(); ++__i)
  652.     __tmp[__i] = __x[__i] < __y[__i];
  653.   return __tmp;  
  654. }
  655.  
  656. #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDER
  657.  
  658. template <class _Tp> 
  659. inline valarray<bool> operator!=(const valarray<_Tp>& __x,
  660.                                  const valarray<_Tp>& __y)
  661. {
  662.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  663.   for (size_t __i = 0; __i < __x.size(); ++__i)
  664.     __tmp[__i] = __x[__i] != __y[__i];
  665.   return __tmp;  
  666. }
  667.  
  668. template <class _Tp> 
  669. inline valarray<bool> operator>(const valarray<_Tp>& __x,
  670.                                 const valarray<_Tp>& __y)
  671. {
  672.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  673.   for (size_t __i = 0; __i < __x.size(); ++__i)
  674.     __tmp[__i] = __x[__i] > __y[__i];
  675.   return __tmp;  
  676. }
  677.  
  678. template <class _Tp> 
  679. inline valarray<bool> operator<=(const valarray<_Tp>& __x,
  680.                                  const valarray<_Tp>& __y)
  681. {
  682.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  683.   for (size_t __i = 0; __i < __x.size(); ++__i)
  684.     __tmp[__i] = __x[__i] <= __y[__i];
  685.   return __tmp;  
  686. }
  687.  
  688. template <class _Tp> 
  689. inline valarray<bool> operator>=(const valarray<_Tp>& __x,
  690.                                  const valarray<_Tp>& __y)
  691. {
  692.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  693.   for (size_t __i = 0; __i < __x.size(); ++__i)
  694.     __tmp[__i] = __x[__i] >= __y[__i];
  695.   return __tmp;  
  696. }
  697.  
  698. #endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */
  699.  
  700. template <class _Tp> 
  701. inline valarray<bool> operator&&(const valarray<_Tp>& __x,
  702.                                  const valarray<_Tp>& __y)
  703. {
  704.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  705.   for (size_t __i = 0; __i < __x.size(); ++__i)
  706.     __tmp[__i] = __x[__i] && __y[__i];
  707.   return __tmp;  
  708. }
  709.  
  710. template <class _Tp> 
  711. inline valarray<bool> operator||(const valarray<_Tp>& __x,
  712.                                  const valarray<_Tp>& __y)
  713. {
  714.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  715.   for (size_t __i = 0; __i < __x.size(); ++__i)
  716.     __tmp[__i] = __x[__i] || __y[__i];
  717.   return __tmp;  
  718. }
  719.  
  720. // Logical operations between an array and a scalar.
  721.  
  722. template <class _Tp>
  723. inline valarray<bool> operator==(const valarray<_Tp>& __x, const _Tp& __c)
  724. {
  725.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  726.   for (size_t __i = 0; __i < __x.size(); ++__i)
  727.     __tmp[__i] = __x[__i] == __c;
  728.   return __tmp;  
  729. }
  730.  
  731. template <class _Tp>
  732. inline valarray<bool> operator==(const _Tp& __c, const valarray<_Tp>& __x)
  733. {
  734.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  735.   for (size_t __i = 0; __i < __x.size(); ++__i)
  736.     __tmp[__i] = __c == __x[__i];
  737.   return __tmp;  
  738. }
  739.  
  740. template <class _Tp>
  741. inline valarray<bool> operator!=(const valarray<_Tp>& __x, const _Tp& __c)
  742. {
  743.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  744.   for (size_t __i = 0; __i < __x.size(); ++__i)
  745.     __tmp[__i] = __x[__i] != __c;
  746.   return __tmp;  
  747. }
  748.  
  749. template <class _Tp>
  750. inline valarray<bool> operator!=(const _Tp& __c, const valarray<_Tp>& __x)
  751. {
  752.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  753.   for (size_t __i = 0; __i < __x.size(); ++__i)
  754.     __tmp[__i] = __c != __x[__i];
  755.   return __tmp;  
  756. }
  757.  
  758. template <class _Tp>
  759. inline valarray<bool> operator<(const valarray<_Tp>& __x, const _Tp& __c)
  760. {
  761.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  762.   for (size_t __i = 0; __i < __x.size(); ++__i)
  763.     __tmp[__i] = __x[__i] < __c;
  764.   return __tmp;  
  765. }
  766.  
  767. template <class _Tp>
  768. inline valarray<bool> operator<(const _Tp& __c, const valarray<_Tp>& __x)
  769. {
  770.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  771.   for (size_t __i = 0; __i < __x.size(); ++__i)
  772.     __tmp[__i] = __c < __x[__i];
  773.   return __tmp;  
  774. }
  775.  
  776. template <class _Tp>
  777. inline valarray<bool> operator>(const valarray<_Tp>& __x, const _Tp& __c)
  778. {
  779.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  780.   for (size_t __i = 0; __i < __x.size(); ++__i)
  781.     __tmp[__i] = __x[__i] > __c;
  782.   return __tmp;  
  783. }
  784.  
  785. template <class _Tp>
  786. inline valarray<bool> operator>(const _Tp& __c, const valarray<_Tp>& __x)
  787. {
  788.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  789.   for (size_t __i = 0; __i < __x.size(); ++__i)
  790.     __tmp[__i] = __c > __x[__i];
  791.   return __tmp;  
  792. }
  793.  
  794. template <class _Tp>
  795. inline valarray<bool> operator<=(const valarray<_Tp>& __x, const _Tp& __c)
  796. {
  797.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  798.   for (size_t __i = 0; __i < __x.size(); ++__i)
  799.     __tmp[__i] = __x[__i]  <= __c;
  800.   return __tmp;  
  801. }
  802.  
  803. template <class _Tp>
  804. inline valarray<bool> operator<=(const _Tp& __c, const valarray<_Tp>& __x)
  805. {
  806.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  807.   for (size_t __i = 0; __i < __x.size(); ++__i)
  808.     __tmp[__i] = __c <= __x[__i];
  809.   return __tmp;  
  810. }
  811.  
  812. template <class _Tp>
  813. inline valarray<bool> operator>=(const valarray<_Tp>& __x, const _Tp& __c)
  814. {
  815.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  816.   for (size_t __i = 0; __i < __x.size(); ++__i)
  817.     __tmp[__i] = __x[__i] >= __c;
  818.   return __tmp;  
  819. }
  820.  
  821. template <class _Tp>
  822. inline valarray<bool> operator>=(const _Tp& __c, const valarray<_Tp>& __x)
  823. {
  824.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  825.   for (size_t __i = 0; __i < __x.size(); ++__i)
  826.     __tmp[__i] = __c >= __x[__i];
  827.   return __tmp;  
  828. }
  829.  
  830. template <class _Tp>
  831. inline valarray<bool> operator&&(const valarray<_Tp>& __x, const _Tp& __c)
  832. {
  833.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  834.   for (size_t __i = 0; __i < __x.size(); ++__i)
  835.     __tmp[__i] = __x[__i] && __c;
  836.   return __tmp;  
  837. }
  838.  
  839. template <class _Tp>
  840. inline valarray<bool> operator&&(const _Tp& __c, const valarray<_Tp>& __x)
  841. {
  842.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  843.   for (size_t __i = 0; __i < __x.size(); ++__i)
  844.     __tmp[__i] = __c && __x[__i];
  845.   return __tmp;  
  846. }
  847.  
  848. template <class _Tp>
  849. inline valarray<bool> operator||(const valarray<_Tp>& __x, const _Tp& __c)
  850. {
  851.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  852.   for (size_t __i = 0; __i < __x.size(); ++__i)
  853.     __tmp[__i] = __x[__i] || __c;
  854.   return __tmp;  
  855. }
  856.  
  857. template <class _Tp>
  858. inline valarray<bool> operator||(const _Tp& __c, const valarray<_Tp>& __x)
  859. {
  860.   valarray<bool> __tmp(__x.size(), valarray<bool>::_NoInit());
  861.   for (size_t __i = 0; __i < __x.size(); ++__i)
  862.     __tmp[__i] = __c || __x[__i];
  863.   return __tmp;  
  864. }
  865.  
  866. // valarray "transcendentals" (the list includes abs and sqrt, which,
  867. // of course, are not transcendental).
  868.  
  869. template <class _Tp>
  870. inline valarray<_Tp> abs(const valarray<_Tp>& __x) {
  871.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  872.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  873.   for (size_t __i = 0; __i < __x.size(); ++__i)
  874.     __tmp[__i] = abs(__x[__i]);
  875.   return __tmp;
  876. }
  877.  
  878. template <class _Tp>
  879. inline valarray<_Tp> acos(const valarray<_Tp>& __x) {
  880.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  881.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  882.   for (size_t __i = 0; __i < __x.size(); ++__i)
  883.     __tmp[__i] = acos(__x[__i]);
  884.   return __tmp;
  885. }
  886.  
  887. template <class _Tp>
  888. inline valarray<_Tp> asin(const valarray<_Tp>& __x) {
  889.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  890.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  891.   for (size_t __i = 0; __i < __x.size(); ++__i)
  892.     __tmp[__i] = asin(__x[__i]);
  893.   return __tmp;
  894. }
  895.  
  896. template <class _Tp>
  897. inline valarray<_Tp> atan(const valarray<_Tp>& __x) {
  898.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  899.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  900.   for (size_t __i = 0; __i < __x.size(); ++__i)
  901.     __tmp[__i] = atan(__x[__i]);
  902.   return __tmp;
  903. }
  904.  
  905. template <class _Tp>
  906. inline valarray<_Tp> atan2(const valarray<_Tp>& __x,
  907.                            const valarray<_Tp>& __y) {
  908.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  909.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  910.   for (size_t __i = 0; __i < __x.size(); ++__i)
  911.     __tmp[__i] = atan2(__x[__i], __y[__i]);
  912.   return __tmp;
  913. }
  914.  
  915. template <class _Tp>
  916. inline valarray<_Tp> atan2(const valarray<_Tp>& __x, const _Tp& __c) {
  917.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  918.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  919.   for (size_t __i = 0; __i < __x.size(); ++__i)
  920.     __tmp[__i] = atan2(__x[__i], __c);
  921.   return __tmp;
  922. }
  923.  
  924. template <class _Tp>
  925. inline valarray<_Tp> atan2(const _Tp& __c, const valarray<_Tp>& __x) {
  926.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  927.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  928.   for (size_t __i = 0; __i < __x.size(); ++__i)
  929.     __tmp[__i] = atan2(__c, __x[__i]);
  930.   return __tmp;
  931. }
  932.  
  933. template <class _Tp>
  934. inline valarray<_Tp> cos(const valarray<_Tp>& __x) {
  935.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  936.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  937.   for (size_t __i = 0; __i < __x.size(); ++__i)
  938.     __tmp[__i] = cos(__x[__i]);
  939.   return __tmp;
  940. }
  941.  
  942. template <class _Tp>
  943. inline valarray<_Tp> cosh(const valarray<_Tp>& __x) {
  944.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  945.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  946.   for (size_t __i = 0; __i < __x.size(); ++__i)
  947.     __tmp[__i] = cosh(__x[__i]);
  948.   return __tmp;
  949. }
  950.  
  951. template <class _Tp>
  952. inline valarray<_Tp> exp(const valarray<_Tp>& __x) {
  953.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  954.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  955.   for (size_t __i = 0; __i < __x.size(); ++__i)
  956.     __tmp[__i] = exp(__x[__i]);
  957.   return __tmp;
  958. }
  959.  
  960. template <class _Tp>
  961. inline valarray<_Tp> log(const valarray<_Tp>& __x) {
  962.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  963.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  964.   for (size_t __i = 0; __i < __x.size(); ++__i)
  965.     __tmp[__i] = log(__x[__i]);
  966.   return __tmp;
  967. }
  968.  
  969. template <class _Tp>
  970. inline valarray<_Tp> log10(const valarray<_Tp>& __x) {
  971.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  972.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  973.   for (size_t __i = 0; __i < __x.size(); ++__i)
  974.     __tmp[__i] = log10(__x[__i]);
  975.   return __tmp;
  976. }
  977.  
  978. template <class _Tp>
  979. inline valarray<_Tp> pow(const valarray<_Tp>& __x,
  980.                            const valarray<_Tp>& __y) {
  981.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  982.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  983.   for (size_t __i = 0; __i < __x.size(); ++__i)
  984.     __tmp[__i] = pow(__x[__i], __y[__i]);
  985.   return __tmp;
  986. }
  987.  
  988. template <class _Tp>
  989. inline valarray<_Tp> pow(const valarray<_Tp>& __x, const _Tp& __c) {
  990.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  991.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  992.   for (size_t __i = 0; __i < __x.size(); ++__i)
  993.     __tmp[__i] = pow(__x[__i], __c);
  994.   return __tmp;
  995. }
  996.  
  997. template <class _Tp>
  998. inline valarray<_Tp> pow(const _Tp& __c, const valarray<_Tp>& __x) {
  999.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  1000.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  1001.   for (size_t __i = 0; __i < __x.size(); ++__i)
  1002.     __tmp[__i] = pow(__c, __x[__i]);
  1003.   return __tmp;
  1004. }
  1005.  
  1006. template <class _Tp>
  1007. inline valarray<_Tp> sin(const valarray<_Tp>& __x) {
  1008.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  1009.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  1010.   for (size_t __i = 0; __i < __x.size(); ++__i)
  1011.     __tmp[__i] = sin(__x[__i]);
  1012.   return __tmp;
  1013. }
  1014.  
  1015. template <class _Tp>
  1016. inline valarray<_Tp> sinh(const valarray<_Tp>& __x) {
  1017.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  1018.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  1019.   for (size_t __i = 0; __i < __x.size(); ++__i)
  1020.     __tmp[__i] = sinh(__x[__i]);
  1021.   return __tmp;
  1022. }
  1023.  
  1024. template <class _Tp>
  1025. inline valarray<_Tp> sqrt(const valarray<_Tp>& __x) {
  1026.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  1027.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  1028.   for (size_t __i = 0; __i < __x.size(); ++__i)
  1029.     __tmp[__i] = sqrt(__x[__i]);
  1030.   return __tmp;
  1031. }
  1032.  
  1033. template <class _Tp>
  1034. inline valarray<_Tp> tan(const valarray<_Tp>& __x) {
  1035.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  1036.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  1037.   for (size_t __i = 0; __i < __x.size(); ++__i)
  1038.     __tmp[__i] = tan(__x[__i]);
  1039.   return __tmp;
  1040. }
  1041.  
  1042. template <class _Tp>
  1043. inline valarray<_Tp> tanh(const valarray<_Tp>& __x) {
  1044.   typedef typename valarray<_Tp>::_NoInit _NoInit;
  1045.   valarray<_Tp> __tmp(__x.size(), _NoInit());
  1046.   for (size_t __i = 0; __i < __x.size(); ++__i)
  1047.     __tmp[__i] = tanh(__x[__i]);
  1048.   return __tmp;
  1049. }
  1050.  
  1051. //----------------------------------------------------------------------
  1052. // slice and slice_array
  1053.  
  1054. class slice {
  1055. public:
  1056.   slice() : _M_start(0), _M_length(0), _M_stride(0) {}
  1057.   slice(size_t __start, size_t __length, size_t __stride)
  1058.     : _M_start(__start), _M_length(__length), _M_stride(__stride)
  1059.     {}
  1060.  
  1061.   size_t start()  const { return _M_start; }
  1062.   size_t size()   const { return _M_length; }
  1063.   size_t stride() const { return _M_stride; }
  1064.  
  1065.    
  1066. private:
  1067.   size_t _M_start;
  1068.   size_t _M_length;
  1069.   size_t _M_stride;
  1070. };
  1071.  
  1072. template <class _Tp>
  1073. class slice_array {
  1074.   friend class valarray<_Tp>;
  1075. public:
  1076.   typedef _Tp value_type;
  1077.  
  1078.   void operator=(const valarray<value_type>& __x) const {
  1079.     size_t __index = _M_slice.start();
  1080.     for (size_t __i = 0;
  1081.          __i < _M_slice.size();
  1082.          ++__i, __index += _M_slice.stride())
  1083.       _M_array[__index] = __x[__i];
  1084.   }
  1085.  
  1086.   void operator*=(const valarray<value_type>& __x) const {
  1087.     size_t __index = _M_slice.start();
  1088.     for (size_t __i = 0;
  1089.          __i < _M_slice.size();
  1090.          ++__i, __index += _M_slice.stride())
  1091.       _M_array[__index] *= __x[__i];
  1092.   }
  1093.  
  1094.   void operator/=(const valarray<value_type>& __x) const {
  1095.     size_t __index = _M_slice.start();
  1096.     for (size_t __i = 0;
  1097.          __i < _M_slice.size();
  1098.          ++__i, __index += _M_slice.stride())
  1099.       _M_array[__index] /= __x[__i];
  1100.   }
  1101.  
  1102.   void operator%=(const valarray<value_type>& __x) const {
  1103.     size_t __index = _M_slice.start();
  1104.     for (size_t __i = 0;
  1105.          __i < _M_slice.size();
  1106.          ++__i, __index += _M_slice.stride())
  1107.       _M_array[__index] %= __x[__i];
  1108.   }
  1109.  
  1110.   void operator+=(const valarray<value_type>& __x) const {
  1111.     size_t __index = _M_slice.start();
  1112.     for (size_t __i = 0;
  1113.          __i < _M_slice.size();
  1114.          ++__i, __index += _M_slice.stride())
  1115.       _M_array[__index] += __x[__i];
  1116.   }
  1117.  
  1118.   void operator-=(const valarray<value_type>& __x) const {
  1119.     size_t __index = _M_slice.start();
  1120.     for (size_t __i = 0;
  1121.          __i < _M_slice.size();
  1122.          ++__i, __index += _M_slice.stride())
  1123.       _M_array[__index] -= __x[__i];
  1124.   }
  1125.  
  1126.   void operator^=(const valarray<value_type>& __x) const {
  1127.     size_t __index = _M_slice.start();
  1128.     for (size_t __i = 0;
  1129.          __i < _M_slice.size();
  1130.          ++__i, __index += _M_slice.stride())
  1131.       _M_array[__index] ^= __x[__i];
  1132.   }
  1133.  
  1134.   void operator&=(const valarray<value_type>& __x) const {
  1135.     size_t __index = _M_slice.start();
  1136.     for (size_t __i = 0;
  1137.          __i < _M_slice.size();
  1138.          ++__i, __index += _M_slice.stride())
  1139.       _M_array[__index] &= __x[__i];
  1140.   }
  1141.  
  1142.   void operator|=(const valarray<value_type>& __x) const {
  1143.     size_t __index = _M_slice.start();
  1144.     for (size_t __i = 0;
  1145.          __i < _M_slice.size();
  1146.          ++__i, __index += _M_slice.stride())
  1147.       _M_array[__index] |= __x[__i];
  1148.   }
  1149.  
  1150.   void operator<<=(const valarray<value_type>& __x) const {
  1151.     size_t __index = _M_slice.start();
  1152.     for (size_t __i = 0;
  1153.          __i < _M_slice.size();
  1154.          ++__i, __index += _M_slice.stride())
  1155.       _M_array[__index] <<= __x[__i];
  1156.   }
  1157.  
  1158.   void operator>>=(const valarray<value_type>& __x) const {
  1159.     size_t __index = _M_slice.start();
  1160.     for (size_t __i = 0;
  1161.          __i < _M_slice.size();
  1162.          ++__i, __index += _M_slice.stride())
  1163.       _M_array[__index] >>= __x[__i];
  1164.   }
  1165.  
  1166.   void operator=(const value_type& __c) const {
  1167.     size_t __index = _M_slice.start();
  1168.     for (size_t __i = 0;
  1169.          __i < _M_slice.size();
  1170.          ++__i, __index += _M_slice.stride())
  1171.       _M_array[__index] = __c;
  1172.   }
  1173.  
  1174.   ~slice_array() {}
  1175.  
  1176. private:
  1177.   slice_array(const slice& __slice, valarray<_Tp>& __array)
  1178.     : _M_slice(__slice), _M_array(__array)
  1179.     {}
  1180.  
  1181.   slice          _M_slice;
  1182.   valarray<_Tp>& _M_array;
  1183.  
  1184. private:                        // Disable assignment and default constructor
  1185.   slice_array();
  1186. };
  1187.  
  1188. // valarray member functions dealing with slice and slice_array
  1189.  
  1190. template <class _Tp>
  1191. inline valarray<_Tp>::valarray(const slice_array<_Tp>& __x)
  1192.   : _Valarray_base<_Tp>(__x._M_slice.size())
  1193. {
  1194.   typedef typename __type_traits<_Tp>::has_trivial_default_constructor
  1195.           _Is_Trivial;
  1196.   _M_initialize(_Is_Trivial());  
  1197.   *this = __x;
  1198. }
  1199.  
  1200. // Behavior is undefined if __x and *this have different sizes
  1201. template <class _Tp>
  1202. valarray<_Tp>& valarray<_Tp>::operator=(const slice_array<_Tp>& __x)
  1203. {
  1204.   size_t __index = __x._M_slice.start();
  1205.   for (size_t __i = 0;
  1206.        __i < __x._M_slice.size();
  1207.        ++__i, __index += __x._M_slice.stride())
  1208.     (*this)[__i] = __x._M_array[__index];
  1209.   return *this;
  1210. }
  1211.  
  1212. template <class _Tp>
  1213. valarray<_Tp> valarray<_Tp>::operator[](slice __slice) const {
  1214.   valarray<_Tp> __tmp(__slice.size(), _NoInit());
  1215.   size_t __index = __slice.start();
  1216.   for (size_t __i = 0;
  1217.        __i < __slice.size();
  1218.        ++__i, __index += __slice.stride())
  1219.     __tmp[__i] = (*this)[__index];
  1220.   return __tmp;
  1221. }
  1222.  
  1223. template <class _Tp>
  1224. inline slice_array<_Tp> valarray<_Tp>::operator[](slice __slice) {
  1225.   return slice_array<_Tp>(__slice, *this);
  1226. }
  1227.  
  1228. //----------------------------------------------------------------------
  1229. // gslice and gslice_array
  1230.  
  1231. struct _Gslice_Iter;
  1232.  
  1233. class gslice {
  1234.   friend struct _Gslice_Iter;
  1235. public:
  1236.   gslice() : _M_start(0), _M_lengths(0), _M_strides(0) {}
  1237.   gslice(size_t __start,
  1238.          const valarray<size_t>& __lengths, const valarray<size_t>& __strides)
  1239.     : _M_start(__start), _M_lengths(__lengths), _M_strides(__strides)
  1240.     {}
  1241.  
  1242.   size_t start()            const { return _M_start; }
  1243.   valarray<size_t> size()   const { return _M_lengths; }
  1244.   valarray<size_t> stride() const { return _M_strides; }
  1245.  
  1246.   // Extension: check for an empty gslice.
  1247.   bool _M_empty() const { return _M_lengths.size() == 0; }
  1248.  
  1249.   // Extension: number of indices this gslice represents.  (For a degenerate
  1250.   // gslice, they're not necessarily all distinct.)
  1251.   size_t _M_size() const {
  1252.     return !this->_M_empty()
  1253.       ? accumulate(_M_lengths._M_first + 1,
  1254.                    _M_lengths._M_first + _M_lengths._M_size,
  1255.                    _M_lengths[0],
  1256.                    multiplies<size_t>())
  1257.       : 0;
  1258.   }
  1259.  
  1260. private:
  1261.   size_t _M_start;
  1262.   valarray<size_t> _M_lengths;
  1263.   valarray<size_t> _M_strides;
  1264. };
  1265.  
  1266. // This is not an STL iterator.  It is constructed from a gslice, and it
  1267. // steps through the gslice indices in sequence.  See 23.3.6 of the C++
  1268. // standard, paragraphs 2-3, for an explanation of the sequence.  At
  1269. // each step we get two things: the ordinal (i.e. number of steps taken),
  1270. // and the one-dimensional index.
  1271.  
  1272. struct _Gslice_Iter {
  1273.   _Gslice_Iter(const gslice& __gslice)
  1274.     : _M_step(0), _M_1d_idx(__gslice.start()),
  1275.       _M_indices(size_t(0), __gslice._M_lengths.size()),
  1276.       _M_gslice(__gslice)
  1277.     {}
  1278.     
  1279.   bool _M_done() const { return _M_indices[0] == _M_gslice._M_lengths[0]; }
  1280.  
  1281.   bool _M_incr() {
  1282.     size_t __dim = _M_indices.size() - 1;
  1283.     ++_M_step;
  1284.     while (true) {
  1285.       _M_1d_idx += _M_gslice._M_strides[__dim];
  1286.       if (++_M_indices[__dim] != _M_gslice._M_lengths[__dim])
  1287.         return true;
  1288.       else if (__dim != 0) {
  1289.         _M_1d_idx -=
  1290.           _M_gslice._M_strides[__dim] * _M_gslice._M_lengths[__dim];
  1291.         _M_indices[__dim] = 0;
  1292.         --__dim;
  1293.       }
  1294.       else
  1295.         return false;
  1296.     }
  1297.   }
  1298.  
  1299.   size_t _M_step;
  1300.   size_t _M_1d_idx;
  1301.  
  1302.   valarray<size_t> _M_indices;
  1303.   const gslice& _M_gslice;
  1304. };
  1305.  
  1306. template <class _Tp>
  1307. class gslice_array {
  1308.   friend class valarray<_Tp>;
  1309. public:
  1310.   typedef _Tp value_type;
  1311.  
  1312.   void operator= (const valarray<value_type>& __x) const {
  1313.     if (!_M_gslice._M_empty()) {
  1314.       _Gslice_Iter __i(_M_gslice);
  1315.       do _M_array[__i._M_1d_idx] = __x[__i._M_step]; while(__i._M_incr());
  1316.     }
  1317.   }
  1318.  
  1319.   void operator*= (const valarray<value_type>& __x) const {
  1320.     if (!_M_gslice._M_empty()) {
  1321.       _Gslice_Iter __i(_M_gslice);
  1322.       do _M_array[__i._M_1d_idx] *= __x[__i._M_step]; while(__i._M_incr());
  1323.     }
  1324.   }
  1325.  
  1326.   void operator/= (const valarray<value_type>& __x) const {
  1327.     if (!_M_gslice._M_empty()) {
  1328.       _Gslice_Iter __i(_M_gslice);
  1329.       do _M_array[__i._M_1d_idx] /= __x[__i._M_step]; while(__i._M_incr());
  1330.     }
  1331.   }
  1332.  
  1333.   void operator%= (const valarray<value_type>& __x) const {
  1334.     if (!_M_gslice._M_empty()) {
  1335.       _Gslice_Iter __i(_M_gslice);
  1336.       do _M_array[__i._M_1d_idx] %= __x[__i._M_step]; while(__i._M_incr());
  1337.     }
  1338.   }
  1339.  
  1340.   void operator+= (const valarray<value_type>& __x) const {
  1341.     if (!_M_gslice._M_empty()) {
  1342.       _Gslice_Iter __i(_M_gslice);
  1343.       do _M_array[__i._M_1d_idx] += __x[__i._M_step]; while(__i._M_incr());
  1344.     }
  1345.   }
  1346.  
  1347.   void operator-= (const valarray<value_type>& __x) const {
  1348.     if (!_M_gslice._M_empty()) {
  1349.       _Gslice_Iter __i(_M_gslice);
  1350.       do _M_array[__i._M_1d_idx] -= __x[__i._M_step]; while(__i._M_incr());
  1351.     }
  1352.   }
  1353.  
  1354.   void operator^= (const valarray<value_type>& __x) const {
  1355.     if (!_M_gslice._M_empty()) {
  1356.       _Gslice_Iter __i(_M_gslice);
  1357.       do _M_array[__i._M_1d_idx] ^= __x[__i._M_step]; while(__i._M_incr());
  1358.     }
  1359.   }
  1360.  
  1361.   void operator&= (const valarray<value_type>& __x) const {
  1362.     if (!_M_gslice._M_empty()) {
  1363.       _Gslice_Iter __i(_M_gslice);
  1364.       do _M_array[__i._M_1d_idx] &= __x[__i._M_step]; while(__i._M_incr());
  1365.     }
  1366.   }
  1367.  
  1368.   void operator|= (const valarray<value_type>& __x) const {
  1369.     if (!_M_gslice._M_empty()) {
  1370.       _Gslice_Iter __i(_M_gslice);
  1371.       do _M_array[__i._M_1d_idx] |= __x[__i._M_step]; while(__i._M_incr());
  1372.     }
  1373.   }
  1374.  
  1375.   void operator<<= (const valarray<value_type>& __x) const {
  1376.     if (!_M_gslice._M_empty()) {
  1377.       _Gslice_Iter __i(_M_gslice);
  1378.       do _M_array[__i._M_1d_idx] <<= __x[__i._M_step]; while(__i._M_incr());
  1379.     }
  1380.   }
  1381.  
  1382.   void operator>>= (const valarray<value_type>& __x) const {
  1383.     if (!_M_gslice._M_empty()) {
  1384.       _Gslice_Iter __i(_M_gslice);
  1385.       do _M_array[__i._M_1d_idx] >>= __x[__i._M_step]; while(__i._M_incr());
  1386.     }
  1387.   }
  1388.  
  1389.   void operator= (const value_type& __c) const {
  1390.     if (!_M_gslice._M_empty()) {
  1391.       _Gslice_Iter __i(_M_gslice);
  1392.       do _M_array[__i._M_1d_idx] = __c; while(__i._M_incr());
  1393.     }
  1394.   }
  1395.  
  1396.   ~gslice_array() {}
  1397.  
  1398. private:                        
  1399.   gslice_array(gslice __gslice, valarray<_Tp>& __array)
  1400.     : _M_gslice(__gslice), _M_array(__array)
  1401.     {}
  1402.  
  1403.   gslice                _M_gslice;
  1404.   valarray<value_type>& _M_array;
  1405.  
  1406. private:                        // Disable assignment
  1407.   void operator=(const gslice_array&);
  1408. };
  1409.  
  1410. // valarray member functions dealing with gslice and gslice_array.  Note
  1411. // that it is illegal (behavior is undefined) to construct a gslice_array
  1412. // from a degenerate gslice.
  1413.  
  1414. template <class _Tp>
  1415. inline valarray<_Tp>::valarray(const gslice_array<_Tp>& __x)
  1416.   : _Valarray_base<_Tp>(__x._M_gslice._M_size())
  1417. {
  1418.   typedef typename __type_traits<_Tp>::has_trivial_default_constructor
  1419.           _Is_Trivial;
  1420.   _M_initialize(_Is_Trivial());  
  1421.   *this = __x;
  1422. }
  1423.  
  1424. // Behavior is undefined if __x and *this have different sizes, or if
  1425. // __x was constructed from a degenerate gslice.
  1426. template <class _Tp>
  1427. valarray<_Tp>& valarray<_Tp>::operator=(const gslice_array<_Tp>& __x)
  1428. {
  1429.   if (this->size() != 0) {
  1430.     _Gslice_Iter __i(__x._M_gslice);
  1431.     do
  1432.       (*this)[__i._M_step] = __x._M_array[__i._M_1d_idx];
  1433.     while(__i._M_incr());
  1434.   }
  1435.   return *this;
  1436. }
  1437.  
  1438. template <class _Tp>
  1439. inline gslice_array<_Tp> valarray<_Tp>::operator[](gslice __slice) {
  1440.   return gslice_array<_Tp>(__slice, *this);
  1441. }
  1442.  
  1443. template <class _Tp>
  1444. valarray<_Tp> valarray<_Tp>::operator[](gslice __slice) const
  1445. {
  1446.   valarray __tmp(__slice._M_size(), _NoInit());
  1447.   if (__tmp.size() != 0) {
  1448.     _Gslice_Iter __i(__slice);
  1449.     do __tmp[__i._M_step] = (*this)[__i._M_1d_idx]; while(__i._M_incr());
  1450.   }
  1451.   return __tmp;
  1452. }
  1453.  
  1454. //----------------------------------------------------------------------
  1455. // mask_array
  1456.  
  1457. template <class _Tp>
  1458. class mask_array {
  1459.   friend class valarray<_Tp>;
  1460. public:
  1461.   typedef _Tp value_type;
  1462.  
  1463.   void operator=(const valarray<value_type>& __x) const {
  1464.     size_t __idx = 0;
  1465.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1466.       if (_M_mask[__i]) _M_array[__i] = __x[__idx++];
  1467.   }
  1468.  
  1469.   void operator*=(const valarray<value_type>& __x) const {
  1470.     size_t __idx = 0;
  1471.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1472.       if (_M_mask[__i]) _M_array[__i] *= __x[__idx++];
  1473.   }
  1474.  
  1475.   void operator/=(const valarray<value_type>& __x) const {
  1476.     size_t __idx = 0;
  1477.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1478.       if (_M_mask[__i]) _M_array[__i] /= __x[__idx++];
  1479.   }
  1480.  
  1481.   void operator%=(const valarray<value_type>& __x) const {
  1482.     size_t __idx = 0;
  1483.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1484.       if (_M_mask[__i]) _M_array[__i] %= __x[__idx++];
  1485.   }
  1486.  
  1487.   void operator+=(const valarray<value_type>& __x) const {
  1488.     size_t __idx = 0;
  1489.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1490.       if (_M_mask[__i]) _M_array[__i] += __x[__idx++];
  1491.   }
  1492.  
  1493.   void operator-=(const valarray<value_type>& __x) const {
  1494.     size_t __idx = 0;
  1495.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1496.       if (_M_mask[__i]) _M_array[__i] -= __x[__idx++];
  1497.   }
  1498.   
  1499.   void operator^=(const valarray<value_type>& __x) const {
  1500.     size_t __idx = 0;
  1501.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1502.       if (_M_mask[__i]) _M_array[__i] ^= __x[__idx++];
  1503.   }
  1504.  
  1505.   void operator&=(const valarray<value_type>& __x) const {
  1506.     size_t __idx = 0;
  1507.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1508.       if (_M_mask[__i]) _M_array[__i] &= __x[__idx++];
  1509.   }
  1510.  
  1511.   void operator|=(const valarray<value_type>& __x) const {
  1512.     size_t __idx = 0;
  1513.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1514.       if (_M_mask[__i]) _M_array[__i] |= __x[__idx++];
  1515.   }
  1516.  
  1517.   void operator<<=(const valarray<value_type>& __x) const {
  1518.     size_t __idx = 0;
  1519.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1520.       if (_M_mask[__i]) _M_array[__i] <<= __x[__idx++];
  1521.   }
  1522.  
  1523.   void operator>>=(const valarray<value_type>& __x) const {
  1524.     size_t __idx = 0;
  1525.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1526.       if (_M_mask[__i]) _M_array[__i] >>= __x[__idx++];
  1527.   }
  1528.  
  1529.   void operator=(const value_type& __c) const {
  1530.     for (size_t __i = 0; __i < _M_array.size(); ++__i)
  1531.       if (_M_mask[__i]) _M_array[__i] = __c;
  1532.   }
  1533.  
  1534.   ~mask_array() {}
  1535.  
  1536.   // Extension: number of true values in the mask
  1537.   size_t _M_num_true() const {
  1538.     size_t __result = 0;
  1539.     for (size_t __i = 0; __i < _M_mask.size(); ++__i)
  1540.       if (_M_mask[__i]) ++__result;
  1541.     return __result;
  1542.   }
  1543.  
  1544. private:
  1545.   mask_array(const valarray<bool>& __mask, valarray<_Tp>& __array)
  1546.     : _M_mask(__mask), _M_array(__array)
  1547.     {}
  1548.  
  1549.   valarray<bool> _M_mask;
  1550.   valarray<_Tp>& _M_array;
  1551.  
  1552. private:                        // Disable assignment
  1553.   void operator=(const mask_array&);
  1554. };
  1555.  
  1556. // valarray member functions dealing with mask_array
  1557.  
  1558. template <class _Tp>
  1559. inline valarray<_Tp>::valarray(const mask_array<_Tp>& __x)
  1560.   : _Valarray_base<_Tp>(__x._M_num_true())
  1561. {
  1562.   typedef typename __type_traits<_Tp>::has_trivial_default_constructor
  1563.           _Is_Trivial;
  1564.   _M_initialize(_Is_Trivial());  
  1565.   *this = __x;
  1566. }
  1567.  
  1568. // Behavior is undefined if __x._M_num_true() != this->size()
  1569. template <class _Tp>
  1570. inline valarray<_Tp>& valarray<_Tp>::operator=(const mask_array<_Tp>& __x) {
  1571.   size_t __idx = 0;
  1572.   for (size_t __i = 0; __i < __x._M_array.size(); ++__i)
  1573.     if (__x._M_mask[__i]) (*this)[__idx++] = __x._M_array[__i];
  1574.   return *this;
  1575. }
  1576.  
  1577. template <class _Tp>
  1578. inline mask_array<_Tp> valarray<_Tp>::operator[](const valarray<bool>& __mask)
  1579. {
  1580.   return mask_array<_Tp>(__mask, *this);
  1581. }
  1582.  
  1583. template <class _Tp>
  1584. valarray<_Tp> valarray<_Tp>::operator[](const valarray<bool>& __mask) const
  1585. {
  1586.   size_t __size = 0;
  1587.   {
  1588.     for (size_t __i = 0; __i < __mask.size(); ++__i)
  1589.       if (__mask[__i]) ++__size;
  1590.   }
  1591.  
  1592.   valarray __tmp(__size, _NoInit());
  1593.   size_t __idx = 0;
  1594.   {
  1595.     for (size_t __i = 0; __i < __mask.size(); ++__i)
  1596.       if (__mask[__i]) __tmp[__idx++] = (*this)[__i];
  1597.   }
  1598.  
  1599.   return __tmp;
  1600. }
  1601.  
  1602. //----------------------------------------------------------------------
  1603. // indirect_array
  1604.  
  1605. template <class _Tp>
  1606. class indirect_array {
  1607.   friend class valarray<_Tp>;
  1608. public:
  1609.   typedef _Tp value_type;
  1610.  
  1611.   void operator=(const valarray<value_type>& __x) const {
  1612.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1613.       _M_array[_M_addr[__i]] = __x[__i];
  1614.   }
  1615.  
  1616.   void operator*=(const valarray<value_type>& __x) const {
  1617.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1618.       _M_array[_M_addr[__i]] *= __x[__i];
  1619.   }
  1620.  
  1621.   void operator/=(const valarray<value_type>& __x) const {
  1622.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1623.       _M_array[_M_addr[__i]] /= __x[__i];
  1624.   }
  1625.  
  1626.   void operator%=(const valarray<value_type>& __x) const {
  1627.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1628.       _M_array[_M_addr[__i]] %= __x[__i];
  1629.   }
  1630.  
  1631.   void operator+=(const valarray<value_type>& __x) const {
  1632.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1633.       _M_array[_M_addr[__i]] += __x[__i];
  1634.   }
  1635.  
  1636.   void operator-=(const valarray<value_type>& __x) const {
  1637.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1638.       _M_array[_M_addr[__i]] -= __x[__i];
  1639.   }
  1640.  
  1641.   void operator^=(const valarray<value_type>& __x) const {
  1642.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1643.       _M_array[_M_addr[__i]] ^= __x[__i];
  1644.   }
  1645.  
  1646.   void operator&=(const valarray<value_type>& __x) const {
  1647.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1648.       _M_array[_M_addr[__i]] &= __x[__i];
  1649.   }
  1650.  
  1651.   void operator|=(const valarray<value_type>& __x) const {
  1652.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1653.       _M_array[_M_addr[__i]] |= __x[__i];
  1654.   }
  1655.  
  1656.   void operator<<=(const valarray<value_type>& __x) const {
  1657.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1658.       _M_array[_M_addr[__i]] <<= __x[__i];
  1659.   }
  1660.  
  1661.   void operator>>=(const valarray<value_type>& __x) const {
  1662.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1663.       _M_array[_M_addr[__i]] >>= __x[__i];
  1664.   }
  1665.  
  1666.   void operator=(const value_type& __c) const {
  1667.     for (size_t __i = 0; __i < _M_addr.size(); ++__i)
  1668.       _M_array[_M_addr[__i]] = __c;
  1669.   }
  1670.  
  1671.   ~indirect_array() {}
  1672.  
  1673. private:
  1674.   indirect_array(const valarray<size_t>& __addr, valarray<_Tp>& __array)
  1675.     : _M_addr(__addr), _M_array(__array)
  1676.     {}
  1677.  
  1678.   valarray<size_t> _M_addr;
  1679.   valarray<_Tp>&   _M_array;
  1680.  
  1681. private:                        // Disable assignment
  1682.   void operator=(const indirect_array&);
  1683. };
  1684.  
  1685. // valarray member functions dealing with indirect_array
  1686.  
  1687. template <class _Tp>
  1688. inline valarray<_Tp>::valarray(const indirect_array<_Tp>& __x)
  1689.   : _Valarray_base<_Tp>(__x._M_addr.size())
  1690. {
  1691.   typedef typename __type_traits<_Tp>::has_trivial_default_constructor
  1692.           _Is_Trivial;
  1693.   _M_initialize(_Is_Trivial());  
  1694.   *this = __x;
  1695. }
  1696.  
  1697. template <class _Tp>
  1698. valarray<_Tp>& valarray<_Tp>::operator=(const indirect_array<_Tp>& __x) {
  1699.   for (size_t __i = 0; __i < __x._M_addr.size(); ++__i)
  1700.     (*this)[__i] = __x._M_array[__x._M_addr[__i]];
  1701.   return *this;
  1702. }
  1703.  
  1704. template <class _Tp>
  1705. inline indirect_array<_Tp>
  1706. valarray<_Tp>::operator[](const valarray<size_t>& __addr)
  1707. {
  1708.   return indirect_array<_Tp>(__addr, *this);
  1709. }
  1710.  
  1711. template <class _Tp>
  1712. valarray<_Tp>
  1713. valarray<_Tp>::operator[](const valarray<size_t>& __addr) const
  1714. {
  1715.   valarray<_Tp> __tmp(__addr.size(), _NoInit());
  1716.   for (size_t __i = 0; __i < __addr.size(); ++__i)
  1717.     __tmp[__i] = (*this)[__addr[__i]];
  1718.   return __tmp;
  1719. }
  1720.  
  1721. //----------------------------------------------------------------------
  1722. // Other valarray noninline member functions
  1723.  
  1724. // Shift and cshift
  1725.  
  1726. template <class _Tp>
  1727. valarray<_Tp> valarray<_Tp>::shift(int __n) const
  1728. {
  1729.   valarray<_Tp> __tmp(this->size());
  1730.  
  1731.   if (__n >= 0) {
  1732.     if (__n < this->size())
  1733.       copy(this->_M_first + __n, this->_M_first + this->size(),
  1734.            __tmp._M_first);
  1735.   }
  1736.   else {
  1737.     if (-__n < this->size())
  1738.       copy(this->_M_first, this->_M_first + this->size() + __n,
  1739.            __tmp._M_first - __n);
  1740.   }
  1741.   return __tmp;
  1742. }
  1743.  
  1744. template <class _Tp>
  1745. valarray<_Tp> valarray<_Tp>::cshift(int __m) const
  1746. {
  1747.   valarray<_Tp> __tmp(this->size());
  1748.  
  1749.   // Reduce __m to an equivalent number in the range [0, size()).  We
  1750.   // have to be careful with negative numbers, since the sign of a % b
  1751.   // is unspecified when a < 0.
  1752.   long __n = __m;
  1753.   if (this->size() < numeric_limits<long>::max())
  1754.     __n %= long(this->size());
  1755.   if (__n < 0)
  1756.     __n += this->size();
  1757.  
  1758.   copy(this->_M_first,       this->_M_first + __n,
  1759.        __tmp._M_first + (this->size() - __n));
  1760.   copy(this->_M_first + __n, this->_M_first + this->size(),
  1761.        __tmp._M_first);
  1762.  
  1763.   return __tmp;
  1764. }
  1765.  
  1766. __STL_END_NAMESPACE
  1767.  
  1768. #endif /* __SGI_STL_VALARRAY */
  1769.  
  1770.  
  1771. // Local Variables:
  1772. // mode:C++
  1773. // End:
  1774.